<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.2">
<title>Caching</title>
<link rel="stylesheet" href="./css/hibernate.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js"></script>
<script>document.addEventListener('DOMContentLoaded', prettyPrint)</script>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="sect1">
<h2 id="caching">Caching</h2>
<div class="sectionbody">
<div class="paragraph">
<p>At runtime, Hibernate handles moving data into and out of the second-level cache in response to the operations performed by the <code>Session</code>, which acts as a transaction-level cache of persistent data.
Once an entity becomes managed, that object is added to the internal cache of the current persistence context (<code>EntityManager</code> or <code>Session</code>).
The persistence context is also called the first-level cache, and it&#8217;s enabled by default.</p>
</div>
<div class="paragraph">
<p>It is possible to configure a JVM-level (<code>SessionFactory</code>-level) or even a cluster cache on a class-by-class and collection-by-collection basis.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Be aware that caches are not aware of changes made to the persistent store by other applications.
They can, however, be configured to regularly expire cached data.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="caching-config">Configuring second-level caching</h3>
<div class="paragraph">
<p>Hibernate can integrate with various caching providers for the purpose of caching data outside the context of a particular <code>Session</code>.
This section defines the settings which control this behavior.</p>
</div>
<div class="sect3">
<h4 id="caching-config-provider">RegionFactory</h4>
<div class="paragraph">
<p><code>org.hibernate.cache.spi.RegionFactory</code> defines the integration between Hibernate and a pluggable caching provider.
<code>hibernate.cache.region.factory_class</code> is used to declare the provider to use.
Hibernate comes with built-in support for the Java caching standard <a href="#caching-provider-jcache">JCache</a>
and also two popular caching libraries: <a href="#caching-provider-ehcache">Ehcache</a> and <a href="#caching-provider-infinispan">Infinispan</a>.
Detailed information is provided later in this chapter.</p>
</div>
</div>
<div class="sect3">
<h4 id="caching-config-properties">Caching configuration properties</h4>
<div class="paragraph">
<p>Besides specific provider configuration, there are a number of configurations options on the Hibernate side of the integration that control various caching behaviors:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>hibernate.cache.use_second_level_cache</code></dt>
<dd>
<p>Enable or disable second level caching overall. Default is true, although the default region factory is <code>NoCachingRegionFactory</code>.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.use_query_cache</code></dt>
<dd>
<p>Enable or disable second level caching of query results. Default is false.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.query_cache_factory</code></dt>
<dd>
<p>Query result caching is handled by a special contract that deals with staleness-based invalidation of the results.
The default implementation does not allow stale results at all. Use this for applications that would like to relax that.
Names an implementation of <code>org.hibernate.cache.spi.QueryCacheFactory</code></p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.use_minimal_puts</code></dt>
<dd>
<p>Optimizes second-level cache operations to minimize writes, at the cost of more frequent reads. Providers typically set this appropriately.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.region_prefix</code></dt>
<dd>
<p>Defines a name to be used as a prefix to all second-level cache region names.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.default_cache_concurrency_strategy</code></dt>
<dd>
<p>In Hibernate second-level caching, all regions can be configured differently including the concurrency strategy to use when accessing that particular region.
This setting allows to define a default strategy to be used.
This setting is very rarely required as the pluggable providers do specify the default strategy to use.
Valid values include:</p>
<div class="ulist">
<ul>
<li>
<p>read-only,</p>
</li>
<li>
<p>read-write,</p>
</li>
<li>
<p>nonstrict-read-write,</p>
</li>
<li>
<p>transactional</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>hibernate.cache.use_structured_entries</code></dt>
<dd>
<p>If <code>true</code>, forces Hibernate to store data in the second-level cache in a more human-friendly format.
Can be useful if you&#8217;d like to be able to "browse" the data directly in your cache, but does have a performance impact.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.auto_evict_collection_cache</code></dt>
<dd>
<p>Enables or disables the automatic eviction of a bidirectional association&#8217;s collection cache entry when the association is changed just from the owning side.
This is disabled by default, as it has a performance impact to track this state.
However if your application does not manage both sides of bidirectional association where the collection side is cached,
the alternative is to have stale data in that collection cache.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.use_reference_entries</code></dt>
<dd>
<p>Enable direct storage of entity references into the second level cache for read-only or immutable entities.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.keys_factory</code></dt>
<dd>
<p>When storing entries into second-level cache as key-value pair, the identifiers can be wrapped into tuples
&lt;entity type, tenant, identifier&gt; to guarantee uniqueness in case that second-level cache stores all entities
in single space. These tuples are then used as keys in the cache. When the second-level cache implementation
(incl. its configuration) guarantees that different entity types are stored separately and multi-tenancy is not
used, you can omit this wrapping to achieve better performance. Currently, this property is only supported when
Infinispan is configured as the second-level cache implementation. Valid values are:</p>
<div class="ulist">
<ul>
<li>
<p><code>default</code> (wraps identitifers in the tuple)</p>
</li>
<li>
<p><code>simple</code> (uses identifiers as keys without any wrapping)</p>
</li>
<li>
<p>fully qualified class name that implements <code>org.hibernate.cache.spi.CacheKeysFactory</code></p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-mappings">Configuring second-level cache mappings</h3>
<div class="paragraph">
<p>The cache mappings can be configured via JPA annotations or XML descriptors or using the Hibernate-specific mapping files.</p>
</div>
<div class="paragraph">
<p>By default, entities are not part of the second level cache and we recommend you to stick to this setting.
However, you can override this by setting the <code>shared-cache-mode</code> element in your <code>persistence.xml</code> file
or by using the <code>javax.persistence.sharedCache.mode</code> property in your configuration file.
The following values are possible:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>ENABLE_SELECTIVE</code> (Default and recommended value)</dt>
<dd>
<p>Entities are not cached unless explicitly marked as cacheable (with the <a href="https://docs.oracle.com/javaee/7/api/javax/persistence/Cacheable.html"><code>@Cacheable</code></a> annotation).</p>
</dd>
<dt class="hdlist1"><code>DISABLE_SELECTIVE</code></dt>
<dd>
<p>Entities are cached unless explicitly marked as non-cacheable.</p>
</dd>
<dt class="hdlist1"><code>ALL</code></dt>
<dd>
<p>Entities are always cached even if marked as non-cacheable.</p>
</dd>
<dt class="hdlist1"><code>NONE</code></dt>
<dd>
<p>No entity is cached even if marked as cacheable.
This option can make sense to disable second-level cache altogether.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The cache concurrency strategy used by default can be set globally via the <code>hibernate.cache.default_cache_concurrency_strategy</code> configuration property.
The values for this property are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">read-only</dt>
<dd>
<p>If your application needs to read, but not modify, instances of a persistent class, a read-only cache is the best choice.
Application can still delete entities and these changes should be reflected in second-level cache so that the cache
does not provide stale entities.
Implementations may use performance optimizations based on the immutability of entities.</p>
</dd>
<dt class="hdlist1">read-write</dt>
<dd>
<p>If the application needs to update data, a read-write cache might be appropriate.
This strategy provides consistent access to single entity, but not a serializable transaction isolation level; e.g. when TX1 reads looks up an entity and does not find it, TX2 inserts the entity into cache and TX1 looks it up again, the new entity can be read in TX1.</p>
</dd>
<dt class="hdlist1">nonstrict-read-write</dt>
<dd>
<p>Similar to read-write strategy but there might be occasional stale reads upon concurrent access to an entity. The choice of this strategy might be appropriate if the application rarely updates the same data simultaneously and strict transaction isolation is not required. Implementations may use performance optimizations that make use of the relaxed consistency guarantee.</p>
</dd>
<dt class="hdlist1">transactional</dt>
<dd>
<p>Provides serializable transaction isolation level.</p>
</dd>
</dl>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Rather than using a global cache concurrency strategy, it is recommended to define this setting on a per entity basis.
Use the <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/annotations/Cache.html"><code>@org.hibernate.annotations.Cache</code></a> annotation for that.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The <code>@Cache</code> annotation define three attributes:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">usage</dt>
<dd>
<p>Defines the <code>CacheConcurrencyStrategy</code></p>
</dd>
<dt class="hdlist1">region</dt>
<dd>
<p>Defines a cache region where entries will be stored</p>
</dd>
<dt class="hdlist1">include</dt>
<dd>
<p>If lazy properties should be included in the second level cache.
The default value is <code>all</code> so lazy properties are cacheable.
The other possible value is <code>non-lazy</code> so lazy properties are not cacheable.</p>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="caching-mappings-inheritance">Entity inheritance and second-level cache mapping</h3>
<div class="paragraph">
<p>When using inheritance, the JPA <code>@Cacheable</code> and the Hibernate-specific <code>@Cache</code> annotations should be declared at the root-entity level only.
That being said, it is not possible to customize the base class <code>@Cacheable</code> or <code>@Cache</code> definition in subclasses.</p>
</div>
<div class="paragraph">
<p>Although the JPA 2.1 specification says that the <code>@Cacheable</code> annotation could be overwritten by a subclass:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>The value of the <code>Cacheable</code> annotation is inherited by subclasses; it can be
overridden by specifying <code>Cacheable</code> on a subclass.</p>
</div>
</blockquote>
<div class="attribution">
&#8212; Section 11.1.7 of the JPA 2.1 Specification
</div>
</div>
<div class="paragraph">
<p>Hibernate requires that a given entity hierarchy share the same caching semantics.</p>
</div>
<div class="paragraph">
<p>The reasons why Hibernate requires that all entities belonging to an inheritance tree share the same caching definition can be summed as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>from a performance perspective, adding an additional check on a per entity type level would slow the bootstrap process.</p>
</li>
<li>
<p>providing different caching semantics for subclasses would violate the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a>.</p>
<div class="paragraph">
<p>Assuming we have a base class, <code>Payment</code> and a subclass <code>CreditCardPayment</code>.
If the <code>Payment</code> is not cacheable and the <code>CreditCardPayment</code> is cached, what should happen when executing the following code snippet:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Payment payment = entityManager.find(Payment.class, creditCardPaymentId);
CreditCardPayment creditCardPayment = (CreditCardPayment) CreditCardPayment;</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this particular case, the second level cache key is formed of the entity class name and the identifier:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">keyToLoad = {org.hibernate.engine.spi.EntityKey@4712}
 identifier = {java.lang.Long@4716} "2"
 persister = {org.hibernate.persister.entity.SingleTableEntityPersister@4629}
  "SingleTableEntityPersister(org.hibernate.userguide.model.Payment)"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Should Hibernate load the <code>CreditCardPayment</code> from the cache as indicated by the actual entity type, or it should not use the cache since the <code>Payment</code> is not supposed to be cached?</p>
</div>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Because of all these intricacies, Hibernate only considers the base class <code>@Cacheable</code> and <code>@Cache</code> definition.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="caching-query">Entity cache</h3>
<div id="caching-entity-mapping-example" class="exampleblock">
<div class="title">Example 1. Entity cache mapping</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">@Entity(name = "Phone")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public static class Phone {

    @Id
    @GeneratedValue
    private Long id;

    private String mobile;

    @ManyToOne
    private Person person;

    @Version
    private int version;

    public Phone() {}

    public Phone(String mobile) {
        this.mobile = mobile;
    }

    public Long getId() {
        return id;
    }

    public String getMobile() {
        return mobile;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Hibernate stores cached entities in a dehydrated form, which is similar to the database representation.
Aside from the foreign key column values of the <code>@ManyToOne</code> or <code>@OneToOne</code> child-side associations,
entity relationships are not stored in the cache,</p>
</div>
<div class="paragraph">
<p>Once an entity is stored in the second-level cache, you can avoid a database hit and load the entity from the cache alone:</p>
</div>
<div id="caching-entity-jpa-example" class="exampleblock">
<div class="title">Example 2. Loading entity using JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Person person = entityManager.find( Person.class, 1L );</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-entity-native-example" class="exampleblock">
<div class="title">Example 3. Loading entity using Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Person person = session.get( Person.class, 1L );</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The Hibernate second-level cache can also load entities by their <a href="chapters/domain/natural_id.html#naturalid">natural id</a>:</p>
</div>
<div id="caching-entity-natural-id-mapping-example" class="exampleblock">
<div class="title">Example 4. Hibernate natural id entity mapping</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">@Entity(name = "Person")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public static class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @NaturalId
    @Column(name = "code", unique = true)
    private String code;

    public Person() {}

    public Person(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-entity-natural-id-example" class="exampleblock">
<div class="title">Example 5. Loading entity using Hibernate native natural id API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Person person = session
    .byNaturalId( Person.class )
    .using( "code", "unique-code")
    .load();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-collection">Collection cache</h3>
<div class="paragraph">
<p>Hibernate can also cache collections, and the <code>@Cache</code> annotation must be on added to the collection property.</p>
</div>
<div class="paragraph">
<p>If the collection is made of value types (basic or embeddables mapped with <code>@ElementCollection</code>),
the collection is stored as such.
If the collection contains other entities (<code>@OneToMany</code> or <code>@ManyToMany</code>),
the collection cache entry will store the entity identifiers only.</p>
</div>
<div id="caching-collection-mapping-example" class="exampleblock">
<div class="title">Example 6. Collection cache mapping</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">@OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List&lt;Phone&gt; phones = new ArrayList&lt;&gt;(  );</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Collections are read-through, meaning they are cached upon being accessed for the first time:</p>
</div>
<div id="caching-collection-example" class="exampleblock">
<div class="title">Example 7. Collection cache usage</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Person person = entityManager.find( Person.class, 1L );
person.getPhones().size();</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Subsequent collection retrievals will use the cache instead of going to the database.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The collection cache is not write-through so any modification will trigger a collection cache entry invalidation.
On a subsequent access, the collection will be loaded from the database and re-cached.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="caching-query">Query cache</h3>
<div class="paragraph">
<p>Aside from caching entities and collections, Hibernate offers a query cache too.
This is useful for frequently executed queries with fixed parameter values.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Caching of query results introduces some overhead in terms of your applications normal transactional processing.
For example, if you cache results of a query against <code>Person</code>,
Hibernate will need to keep track of when those results should be invalidated because changes have been committed against any <code>Person</code> entity.</p>
</div>
<div class="paragraph">
<p>That, coupled with the fact that most applications simply gain no benefit from caching query results,
leads Hibernate to disable caching of query results by default.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To use query caching, you will first need to enable it with the following configuration property:</p>
</div>
<div id="caching-query-configuration" class="exampleblock">
<div class="title">Example 8. Enabling query cache</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.use_query_cache"
    value="true" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As mentioned above, most queries do not benefit from caching or their results.
So by default, individual queries are not cached even after enabling query caching.
Each particular query that needs to be cached must be manually set as cacheable.
This way, the query looks for existing cache results or adds the query results to the cache when being executed.</p>
</div>
<div id="caching-query-jpa-example" class="exampleblock">
<div class="title">Example 9. Caching query using JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = entityManager.createQuery(
    "select p " +
    "from Person p " +
    "where p.name = :name", Person.class)
.setParameter( "name", "John Doe")
.setHint( "org.hibernate.cacheable", "true")
.getResultList();</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-query-native-example" class="exampleblock">
<div class="title">Example 10. Caching query using Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.name = :name")
.setParameter( "name", "John Doe")
.setCacheable(true)
.list();</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The query cache does not cache the state of the actual entities in the cache;
it caches only identifier values and results of value type.</p>
</div>
<div class="paragraph">
<p>Just as with collection caching, the query cache should always be used in conjunction with the second-level cache for those entities expected to be cached as part of a query result cache.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="caching-query-region">Query cache regions</h4>
<div class="paragraph">
<p>This setting creates two new cache regions:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>org.hibernate.cache.internal.StandardQueryCache</code></dt>
<dd>
<p>Holding the cached query results</p>
</dd>
<dt class="hdlist1"><code>org.hibernate.cache.spi.UpdateTimestampsCache</code></dt>
<dd>
<p>Holding timestamps of the most recent updates to queryable tables.
These are used to validate the results as they are served from the query cache.</p>
</dd>
</dl>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If you configure your underlying cache implementation to use expiration, it&#8217;s very important that the timeout of the underlying cache region for the <code>UpdateTimestampsCache</code> is set to a higher value than the timeouts of any of the query caches.</p>
</div>
<div class="paragraph">
<p>In fact, we recommend that the <code>UpdateTimestampsCache</code> region is not configured for expiration (time-based) or eviction (size/memory-based) at all.
Note that an LRU (Least Recently Used) cache eviction policy is never appropriate for this particular cache region.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you require fine-grained control over query cache expiration policies,
you can specify a named cache region for a particular query.</p>
</div>
<div id="caching-query-region-jpa-example" class="exampleblock">
<div class="title">Example 11. Caching query in custom region using JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = entityManager.createQuery(
        "select p " +
        "from Person p " +
        "where p.id &gt; :id", Person.class)
        .setParameter( "id", 0L)
        .setHint( QueryHints.HINT_CACHEABLE, "true")
        .setHint( QueryHints.HINT_CACHE_REGION, "query.cache.person" )
        .getResultList();</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-query-region-native-example" class="exampleblock">
<div class="title">Example 12. Caching query in custom region using Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.id &gt; :id")
.setParameter( "id", 0L)
.setCacheable(true)
.setCacheRegion( "query.cache.person" )
.list();</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you want to force the query cache to refresh one of its regions (disregarding any cached results it finds there),
you can use custom cache modes.</p>
</div>
<div id="caching-query-region-store-mode-jpa-example" class="exampleblock">
<div class="title">Example 13. Using custom query cache mode with JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = entityManager.createQuery(
    "select p " +
    "from Person p " +
    "where p.id &gt; :id", Person.class)
.setParameter( "id", 0L)
.setHint( QueryHints.HINT_CACHEABLE, "true")
.setHint( QueryHints.HINT_CACHE_REGION, "query.cache.person" )
.setHint( "javax.persistence.cache.storeMode", CacheStoreMode.REFRESH )
.getResultList();</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-query-region-native-example" class="exampleblock">
<div class="title">Example 14. Using custom query cache mode with Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.id &gt; :id")
.setParameter( "id", 0L)
.setCacheable(true)
.setCacheRegion( "query.cache.person" )
.setCacheMode( CacheMode.REFRESH )
.list();</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>When using <a href="http://docs.oracle.com/javaee/7/api/javax/persistence/CacheStoreMode.html#REFRESH"><code>CacheStoreMode.REFRESH</code></a> or <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/CacheMode.html#REFRESH"><code>CacheMode.REFRESH</code></a> in conjunction with the region you have defined for the given query,
Hibernate will selectively force the results cached in that particular region to be refreshed.</p>
</div>
<div class="paragraph">
<p>This is particularly useful in cases where underlying data may have been updated via a separate process
and is a far more efficient alternative to bulk eviction of the region via <code>SessionFactory</code> eviction which looks as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">session.getSessionFactory().getCache().evictQueryRegion( "query.cache.person" );</code></pre>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-management">Managing the cached data</h3>
<div class="paragraph">
<p>Traditionally, Hibernate defined the <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/CacheMode.html"><code>CacheMode</code></a> enumeration to describe
the ways of interactions with the cached data.
JPA split cache modes by storage (<a href="http://docs.oracle.com/javaee/7/api/javax/persistence/CacheStoreMode.html"><code>CacheStoreMode</code></a>)
and retrieval (<a href="http://docs.oracle.com/javaee/7/api/javax/persistence/CacheRetrieveMode.html"><code>CacheRetrieveMode</code></a>).</p>
</div>
<div class="paragraph">
<p>The relationship between Hibernate and JPA cache modes can be seen in the following table:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. Cache modes relationships</caption>
<colgroup>
<col style="width: %;">
<col style="width: %;">
<col style="width: %;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Hibernate</th>
<th class="tableblock halign-left valign-top">JPA</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheMode.NORMAL</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheStoreMode.USE</code> and <code>CacheRetrieveMode.USE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Default. Reads/writes data from/into cache</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheMode.REFRESH</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheStoreMode.REFRESH</code> and <code>CacheRetrieveMode.BYPASS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Doesn&#8217;t read from cache, but writes to the cache upon loading from the database</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheMode.PUT</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheStoreMode.USE</code> and <code>CacheRetrieveMode.BYPASS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Doesn&#8217;t read from cache, but writes to the cache as it reads from the database</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheMode.GET</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheStoreMode.BYPASS</code> and <code>CacheRetrieveMode.USE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Read from the cache, but doesn&#8217;t write to cache</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheMode.IGNORE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CacheStoreMode.BYPASS</code> and <code>CacheRetrieveMode.BYPASS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Doesn&#8217;t read/write data from/into cache</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Setting the cache mode can be done either when loading entities directly or when executing a query.</p>
</div>
<div id="caching-management-cache-mode-entity-jpa-example" class="exampleblock">
<div class="title">Example 15. Using custom cache modes with JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Map&lt;String, Object&gt; hints = new HashMap&lt;&gt;(  );
hints.put( "javax.persistence.cache.retrieveMode " , CacheRetrieveMode.USE );
hints.put( "javax.persistence.cache.storeMode" , CacheStoreMode.REFRESH );
Person person = entityManager.find( Person.class, 1L , hints);</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-management-cache-mode-entity-native-example" class="exampleblock">
<div class="title">Example 16. Using custom cache modes with Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">session.setCacheMode( CacheMode.REFRESH );
Person person = session.get( Person.class, 1L );</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The custom cache modes can be set for queries as well:</p>
</div>
<div id="caching-management-cache-mode-query-jpa-example" class="exampleblock">
<div class="title">Example 17. Using custom cache modes for queries with JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = entityManager.createQuery(
    "select p from Person p", Person.class)
.setHint( QueryHints.HINT_CACHEABLE, "true")
.setHint( "javax.persistence.cache.retrieveMode " , CacheRetrieveMode.USE )
.setHint( "javax.persistence.cache.storeMode" , CacheStoreMode.REFRESH )
.getResultList();</code></pre>
</div>
</div>
</div>
</div>
<div id="caching-management-cache-mode-query-native-example" class="exampleblock">
<div class="title">Example 18. Using custom cache modes for queries with Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">List&lt;Person&gt; persons = session.createQuery(
    "select p from Person p" )
.setCacheable( true )
.setCacheMode( CacheMode.REFRESH )
.list();</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="caching-management-evict">Evicting cache entries</h4>
<div class="paragraph">
<p>Because the second level cache is bound to the <code>EntityManagerFactory</code> or the <code>SessionFactory</code>,
cache eviction must be done through these two interfaces.</p>
</div>
<div class="paragraph">
<p>JPA only supports entity eviction through the <a href="https://docs.oracle.com/javaee/7/api/javax/persistence/Cache.html"><code>javax.persistence.Cache</code></a> interface:</p>
</div>
<div id="caching-management-evict-jpa-example" class="exampleblock">
<div class="title">Example 19. Evicting entities with JPA</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">entityManager.getEntityManagerFactory().getCache().evict( Person.class );</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Hibernate is much more flexible in this regard as it offers fine-grained control over what needs to be evicted.
The <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Cache.html"><code>org.hibernate.Cache</code></a> interface defines various evicting strategies:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>entities (by their class or region)</p>
</li>
<li>
<p>entities stored using the natural-id (by their class or region)</p>
</li>
<li>
<p>collections (by the region, and it might take the collection owner identifier as well)</p>
</li>
<li>
<p>queries (by region)</p>
</li>
</ul>
</div>
<div id="caching-management-evict-native-example" class="exampleblock">
<div class="title">Example 20. Evicting entities with Hibernate native API</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">session.getSessionFactory().getCache().evictQueryRegion( "query.cache.person" );</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-statistics">Caching statistics</h3>
<div class="paragraph">
<p>If you enable the <code>hibernate.generate_statistics</code> configuration property,
Hibernate will expose a number of metrics via <code>SessionFactory.getStatistics()</code>.
Hibernate can even be configured to expose these statistics via JMX.</p>
</div>
<div class="paragraph">
<p>This way, you can get access to the <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/stat/Statistics.html"><code>Statistics</code></a> class which comprises all sort of
second-level cache metrics.</p>
</div>
<div id="caching-statistics-example" class="exampleblock">
<div class="title">Example 21. Caching statistics</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-JAVA" data-lang="JAVA">Statistics statistics = session.getSessionFactory().getStatistics();
SecondLevelCacheStatistics secondLevelCacheStatistics =
        statistics.getSecondLevelCacheStatistics( "query.cache.person" );
long hitCount = secondLevelCacheStatistics.getHitCount();
long missCount = secondLevelCacheStatistics.getMissCount();
double hitRatio = (double) hitCount / ( hitCount + missCount );</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-provider-jcache">JCache</h3>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Use of the build-in integration for <a href="https://jcp.org/en/jsr/detail?id=107">JCache</a> requires that the <code>hibernate-jcache</code> module jar (and all of its dependencies) are on the classpath.
In addition a JCache implementation needs to be added as well.
A list of compatible implementations can be found <a href="https://jcp.org/aboutJava/communityprocess/implementations/jsr107/index.html">on the JCP website</a>.
An alternative source of compatible implementations can be found through <a href="https://github.com/cruftex/jsr107-test-zoo">the JSR-107 test zoo</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="caching-provider-jcache-region-factory">RegionFactory</h4>
<div class="paragraph">
<p>The <code>hibernate-jcache</code> module defines the following region factory: <code>JCacheRegionFactory</code>.</p>
</div>
<div class="paragraph">
<p>To use the <code>JCacheRegionFactory</code>, you need to specify the following configuration property:</p>
</div>
<div id="caching-provider-jcache-region-factory-example" class="exampleblock">
<div class="title">Example 22. <code>JCacheRegionFactory</code> configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.region.factory_class"
    value="org.hibernate.cache.jcache.JCacheRegionFactory"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code>JCacheRegionFactory</code> configures a <code>javax.cache.CacheManager</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="caching-provider-jcache-cache-manager">JCache <code>CacheManager</code></h4>
<div class="paragraph">
<p>JCache mandates that <code>CacheManager</code>s sharing the same URI and class loader be unique in JVM.</p>
</div>
<div class="paragraph">
<p>If you do not specify additional properties, the <code>JCacheRegionFactory</code> will load the default JCache provider and create the default <code>CacheManager</code>.
Also, <code>Cache</code>s will be created using the default <code>javax.cache.configuration.MutableConfiguration</code>.</p>
</div>
<div class="paragraph">
<p>In order to control which provider to use and specify configuration for the <code>CacheManager</code> and <code>Cache</code>s you can use the following two properties:</p>
</div>
<div id="caching-provider-jcache-region-factory-config-example" class="exampleblock">
<div class="title">Example 23. JCache configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.javax.cache.provider"
    value="org.ehcache.jsr107.EhcacheCachingProvider"/&gt;
&lt;property
    name="hibernate.javax.cache.uri"
    value="file:/path/to/ehcache.xml"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Only by specifying the second property <code>hibernate.javax.cache.uri</code> will you be able to have a <code>CacheManager</code> per <code>SessionFactory</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-provider-ehcache">Ehcache</h3>
<div class="paragraph">
<p>This integration covers Ehcache 2.x, in order to use Ehcache 3.x as second level cache, refer to the <a href="#caching-provider-jcache">JCache integration</a>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Use of the build-in integration for <a href="http://www.ehcache.org/">Ehcache</a> requires that the <code>hibernate-ehcache</code> module jar (and all of its dependencies) are on the classpath.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="caching-provider-ehcache-region-factory">RegionFactory</h4>
<div class="paragraph">
<p>The hibernate-ehcache module defines two specific region factories: <code>EhCacheRegionFactory</code> and <code>SingletonEhCacheRegionFactory</code>.</p>
</div>
<div class="sect4">
<h5 id="caching-provider-ehcache-region-factory-shared"><code>EhCacheRegionFactory</code></h5>
<div class="paragraph">
<p>To use the <code>EhCacheRegionFactory</code>, you need to specify the following configuration property:</p>
</div>
<div id="caching-provider-ehcache-region-factory-shared-example" class="exampleblock">
<div class="title">Example 24. <code>EhCacheRegionFactory</code> configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.region.factory_class"
    value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code>EhCacheRegionFactory</code> configures a <code>net.sf.ehcache.CacheManager</code> for each <code>SessionFactory</code>,
so the <code>CacheManager</code> is not shared among multiple <code>SessionFactory</code> instances in the same JVM.</p>
</div>
</div>
<div class="sect4">
<h5 id="caching-provider-ehcache-region-factory-singleton"><code>SingletonEhCacheRegionFactory</code></h5>
<div class="paragraph">
<p>To use the <code>SingletonEhCacheRegionFactory</code>, you need to specify the following configuration property:</p>
</div>
<div id="caching-provider-ehcache-region-factory-singleton-example" class="exampleblock">
<div class="title">Example 25. <code>SingletonEhCacheRegionFactory</code> configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.region.factory_class"
    value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code>SingletonEhCacheRegionFactory</code> configures a singleton <code>net.sf.ehcache.CacheManager</code> (see <a href="http://www.ehcache.org/apidocs/2.8.4/net/sf/ehcache/CacheManager.html#create%28%29">CacheManager#create()</a>),
shared among multiple <code>SessionFactory</code> instances in the same JVM.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p><a href="http://www.ehcache.org/documentation/2.8/integrations/hibernate#optional">Ehcache documentation</a> recommends using multiple non-singleton <code>CacheManager(s)</code> when there are multiple Hibernate <code>SessionFactory</code> instances running in the same JVM.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="caching-provider-infinispan">Infinispan</h3>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Use of the build-in integration for <a href="http://infinispan.org/">Infinispan</a> requires that the <code>hibernate-infinispan module</code> jar (and all of its dependencies) are on the classpath.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>How to configure Infinispan to be the second level cache provider varies slightly depending on the deployment scenario:</p>
</div>
<div class="sect3">
<h4 id="_single_node_local">Single Node Local</h4>
<div class="paragraph">
<p>In standalone library mode, a JPA/Hibernate application runs inside a Java SE application or inside containers that don&#8217;t offer Infinispan integration.</p>
</div>
<div class="paragraph">
<p>Enabling Infinispan second level cache provider inside a JPA/Hibernate application that runs in single node is very straightforward.
First, make sure the Hibernate Infinispan cache provider (and its dependencies) are available in the classpath, then modify the persistence.xml to include these properties:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;!-- Use Infinispan second level cache provider --&gt;
&lt;property name="hibernate.cache.region.factory_class"
          value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/&gt;

&lt;!-- Optional: Force using local configuration when only using a single node.
     Otherwise a clustered configuration is loaded. --&gt;
&lt;property name="hibernate.cache.infinispan.cfg"
          value="org/hibernate/cache/infinispan/builder/infinispan-configs-local.xml"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Plugging in Infinispan as second-level cache provider requires at the bare minimum that <code>hibernate.cache.region.factory_class</code> is set to an Infinispan region factory implementation.
Normally, this is <code>org.hibernate.cache.infinispan.InfinispanRegionFactory</code> but other region factories are possible in alternative scenarios (see <a href="#caching-provider-infinispan-region-factory">Alternative Region Factory</a> section for more info).</p>
</div>
<div class="paragraph">
<p>By default, the Infinispan second-level cache provider uses an Infinispan configuration that&#8217;s designed for clustered environments.
However, since this section is focused on running Infinispan second-level cache provider in a single node, an Infinispan configuration designed for local environments is recommended.
To enable that configuration, set <code>hibernate.cache.infinispan.cfg</code> to <code>org/hibernate/cache/infinispan/builder/infinispan-configs-local.xml</code> value.</p>
</div>
<div class="paragraph">
<p>The next section focuses on analysing how the default local configuration works.
Changing Infinispan configuration options can be done following the instructions in <a href="#caching-provider-infinispan-config">Configuration Properties</a> section.</p>
</div>
<div class="sect4">
<h5 id="_default_local_configuration">Default Local Configuration</h5>
<div class="paragraph">
<p>Infinispan second-level cache provider comes with a configuration designed for local, single node, environments.
These are the characteristics of such configuration:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Entities, collections, queries and timestamps are stored in non-transactional local caches.</p>
</li>
<li>
<p>Entities and collections query caches are configured with the following eviction settings.
You can change these settings on a per entity or collection basis or per individual entity or collection type.
More information in the <a href="#integrations:infinispan-2lc-advanced">Advanced Configuration</a> section below.</p>
<div class="ulist">
<ul>
<li>
<p>Eviction wake up interval is 5 seconds.</p>
</li>
<li>
<p>Max number of entries are 10,000</p>
</li>
<li>
<p>Max idle time before expiration is 100 seconds</p>
</li>
<li>
<p>Default eviction algorithm is LRU, least recently used.</p>
</li>
</ul>
</div>
</li>
<li>
<p><em>No eviction/expiration is configured for timestamp caches</em>, nor it&#8217;s allowed.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_local_cache_strategies">Local Cache Strategies</h5>
<div class="paragraph">
<p>Before version 5.0, Infinispan only supported <code>transactional</code> and <code>read-only</code> strategies.</p>
</div>
<div class="paragraph">
<p>Starting with version 5.0, all cache strategies are supported: <code>transactional</code>, <code>read-write</code>, <code>nonstrict-read-write</code> and <code>read-only</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_multi_node_cluster">Multi Node Cluster</h4>
<div class="paragraph">
<p>When running a JPA/Hibernate in a multi-node environment and enabling Infinispan second-level cache, it is necessary to cluster the second-level cache so that cache consistency can be guaranteed.
Clustering the Infinispan second-level cache provider is as simple as adding the following properties:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;!-- Use Infinispan second level cache provider --&gt;
&lt;property name="hibernate.cache.region.factory_class"
          value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As with the standalone local mode, at the bare minimum the region factory has to be configured to point to an Infinispan region factory implementation.</p>
</div>
<div class="paragraph">
<p>However, the default Infinispan configuration used by the second-level cache provider is already configured to work in a cluster environment, so no need to add any extra properties.</p>
</div>
<div class="paragraph">
<p>The next section focuses on analysing how the default cluster configuration works.
Changing Infinispan configuration options can be done following the instructions in <a href="#caching-provider-infinispan-config">Configuration Properties</a> section.</p>
</div>
<div class="sect4">
<h5 id="integrations:infinispan-2lc-cluster-configuration">Default Cluster Configuration</h5>
<div class="paragraph">
<p>Infinispan second-level cache provider default configuration is designed for multi-node clustered environments.
The aim of this section is to explain the default settings for each of the different global data type caches (entity, collection, query and timestamps), why these were chosen and what are the available alternatives.
These are the characteristics of such configuration:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>For all entities and collections, whenever a new <em>entity or collection is read from database</em> and needs to be cached, <em>it&#8217;s only cached locally</em> in order to reduce intra-cluster traffic.
This option can be changed so that entities/collections are cached cluster wide, by switching the entity/collection cache to be replicated or distributed.
How to change this option is explained in the <a href="#caching-provider-infinispan-config">Configuration Properties</a> section.</p>
</li>
<li>
<p>All <em>entities and collections are configured to use a synchronous invalidation</em> as clustering mode.
This means that when an entity is updated, the updated cache will send a message to the other members of the cluster telling them that the entity has been modified.
Upon receipt of this message, the other nodes will remove this data from their local cache, if it was stored there.
This option can be changed so that both local and remote nodes contain the updates by configuring entities or collections to use a replicated or distributed cache.
With replicated caches all nodes would contain the update, whereas with distributed caches only a subset of the nodes.
How to change this option is explained in the <a href="#caching-provider-infinispan-config">Configuration Properties</a> section.</p>
</li>
<li>
<p>All <em>entities and collections have initial state transfer disabled</em> since there&#8217;s no need for it.</p>
</li>
<li>
<p>Entities and collections are configured with the following eviction settings.
You can change these settings on a per entity or collection basis or per individual entity or collection type.
More information in the <a href="#caching-provider-infinispan-config">Configuration Properties</a> section below.</p>
<div class="ulist">
<ul>
<li>
<p>Eviction wake up interval is 5 seconds.</p>
</li>
<li>
<p>Max number of entries are 10,000</p>
</li>
<li>
<p>Max idle time before expiration is 100 seconds</p>
</li>
<li>
<p>Default eviction algorithm is LRU, least recently used.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Assuming that query caching has been enabled for the persistence unit (see <a href="#caching-query">query cache section</a>), the query cache is configured so that <em>queries are only cached locally</em>.
Alternatively, you can configure query caching to use replication by selecting the <code>replicated-query</code> as query cache name.
However, replication for query cache only makes sense if, and only if, all of this conditions are true:</p>
<div class="ulist">
<ul>
<li>
<p>Performing the query is quite expensive.</p>
</li>
<li>
<p>The same query is very likely to be repeatedly executed on different cluster nodes.</p>
</li>
<li>
<p>The query is unlikely to be invalidated out of the cache (Note: Hibernate must aggressively invalidate query results from the cache any time any instance of one of the entity types targeted by the query. All such query results are invalidated, even if the change made to the specific entity instance would not have affected the query result)</p>
</li>
</ul>
</div>
</li>
<li>
<p><em>query cache</em> uses the <em>same eviction/expiration settings as for entities/collections</em>.</p>
</li>
<li>
<p><em>query cache has initial state transfer disabled</em> . It is not recommended that this is enabled.</p>
</li>
<li>
<p>The <em>timestamps cache is configured with asynchronous replication</em> as clustering mode.
Local or invalidated cluster modes are not allowed, since all cluster nodes must store all timestamps.
As a result, <em>no eviction/expiration is allowed for timestamp caches either</em>.</p>
</li>
</ul>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Asynchronous replication was selected as default for timestamps cache for performance reasons.
A side effect of this choice is that when an entity/collection is updated, for a very brief period of time stale queries might be returned.
It&#8217;s important to note that due to how Infinispan deals with asynchronous replication, stale queries might be found even query is done right after an entity/collection update on same node.
The reason why asynchronous replication works this way is because there&#8217;s a single node that&#8217;s owner for a given key, and that enables changes to be applied in the same order in all nodes.
Without it, it could happen that an older value could replace a newer value in certain nodes.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Hibernate must aggressively invalidate query results from the cache any time any instance of one of the entity types is modified. All cached query results referencing given entity type are invalidated, even if the change made to the specific entity instance would not have affected the query result.
The timestamps cache plays here an important role - it contains last modification timestamp for each entity type. After a cached query results is loaded, its timestamp is compared to all timestamps of the entity types that are referenced in the query and if any of these is higher, the cached query result is discarded and the query is executed against DB.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect4">
<h5 id="_cluster_cache_strategies">Cluster Cache Strategies</h5>
<div class="paragraph">
<p>Before version 5.0, Infinispan only supported <code>transactional</code> and <code>read-only</code> strategies on top of <em>transactional invalidation</em> caches.</p>
</div>
<div class="paragraph">
<p>Since version 5.0, Infinispan currently supports all cache concurrency modes in cluster mode, although not all combinations of configurations are compatible:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>non-transactional invalidation</em> caches are supported as well with <code>read-write</code> strategy. The actual setting of cache concurrency mode (<code>read-write</code> vs. <code>transactional</code>) is not honored, the appropriate strategy is selected based on the cache configuration (<em>non-transactional</em> vs. <em>transactional</em>).</p>
</li>
<li>
<p><code>read-write</code> mode is supported on <em>non-transactional distributed/replicated</em> caches, however, eviction should not be used in this configuration. Use of eviction can lead to consistency issues. Expiration (with reasonably long max-idle times) can be used.</p>
</li>
<li>
<p><code>nonstrict-read-write</code> mode is supported on <em>non-transactional distributed/replicated</em> caches, but the eviction should be turned off as well. In addition to that, the entities must use versioning. This mode mildly relaxes the consistency - between DB commit and end of transaction commit a stale read (see <a href="#caching-provider-infinispan-stale-read-example">example</a>) may occur in another transaction. However this strategy uses less RPCs and can be more performant than the other ones.</p>
</li>
<li>
<p><code>read-only</code> mode is supported on both <em>transactional</em> and <em>non-transactional</em> <em>invalidation</em> caches and <em>non-transactional distributed/replicated</em> caches, but use of this mode currently does not bring any performance gains.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The available combinations are summarized in table below:</p>
</div>
<table id="caching-provider-infinispan-compatibility-table" class="tableblock frame-all grid-all spread">
<caption class="title">Table 2. Cache concurrency strategy/cache mode compatibility table</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Concurrency strategy</th>
<th class="tableblock halign-left valign-top">Cache transactions</th>
<th class="tableblock halign-left valign-top">Cache mode</th>
<th class="tableblock halign-left valign-top">Eviction</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">transactional</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">transactional</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">invalidation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">read-write</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">non-transactional</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">invalidation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">read-write</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">non-transactional</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">distributed/replicated</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nonstrict-read-write</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">non-transactional</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">distributed/replicated</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Changing caches to behave different to the default behaviour explained in previous section is explained in <a href="#caching-provider-infinispan-config">Configuration Properties</a> section.</p>
</div>
<div id="caching-provider-infinispan-stale-read-example" class="exampleblock">
<div class="title">Example 26. Stale read with <code>nonstrict-read-write</code> strategy</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code>A=0 (non-cached), B=0 (cached in 2LC)
TX1: write A = 1, write B = 1
TX1: start commit
TX1: commit A, B in DB
TX2: read A = 1 (from DB), read B = 0 (from 2LC) // breaks transactional atomicity
TX1: update A, B in 2LC
TX1: end commit
Tx3: read A = 1, B = 1 // reads after TX1 commit completes are consistent again</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="caching-provider-infinispan-region-factory">Alternative RegionFactory</h4>
<div class="paragraph">
<p>In standalone environments or managed environments with no Infinispan integration, <code>org.hibernate.cache.infinispan.InfinispanRegionFactory</code> should be the choice for region factory implementation.
However, it might be sometimes desirable for the Infinispan cache manager to be shared between different JPA/Hibernate applications, for example to share intra-cluster communications channels.
In this case, the Infinispan cache manager could be bound into JNDI and the JPA/Hibernate applications could use an alternative region factory implementation:</p>
</div>
<div id="caching-provider-infinispan-region-factory-jndi-example" class="exampleblock">
<div class="title">Example 27. <code>JndiInfinispanRegionFactory</code> configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.region.factory_class"
    value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory" /&gt;

&lt;property
    name="hibernate.cache.infinispan.cachemanager"
    value="java:CacheManager" /&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_inside_wildfly">Inside Wildfly</h4>
<div class="paragraph">
<p>In WildFly, Infinispan is the default second level cache provider for JPA/Hibernate.
When using JPA in WildFly, region factory is automatically set upon configuring <code>hibernate.cache.use_second_level_cache=true</code> (by default second-level cache is not used).</p>
</div>
<div class="paragraph">
<p>You can find details about its configuration in <a href="{wildflydocroot}/JPA%20Reference%20Guide">the JPA reference guide</a>, in particular, in the <a href="{wildflydocroot}/JPA%20Reference%20Guide#JPAReferenceGuide-UsingtheInfinispansecondlevelcache">second level cache</a> section.</p>
</div>
<div class="paragraph">
<p>The default second-level cache configurations used by Wildfly match the configurations explained above both for local and clustered environments.
So, an Infinispan based second-level cache should behave exactly the same standalone and within containers that provide Infinispan second-level cache as default for JPA/Hibernate.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Remember that if deploying to Wildfly or Application Server, the way some Infinispan second level cache provider configuration is defined changes slightly because the properties must include deployment and persistence information.
Check the <a href="#caching-provider-infinispan-config">Configuration</a> section for more details.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="caching-provider-infinispan-config">Configuration properties</h4>
<div class="paragraph">
<p>As explained above, Infinispan second-level cache provider comes with default configuration in <code>infinispan-config.xml</code> that is suited for clustered use.
If there&#8217;s only single JVM accessing the DB, you can use more performant <code>infinispan-config-local.xml</code> by setting the <code>hibernate.cache.infinispan.cfg</code> property.
If you require further tuning of the cache, you can provide your own configuration.
Caches that are not specified in the provided configuration will default to <code>infinispan-config.xml</code> (if the provided configuration uses clustering) or <code>infinispan-config-local.xml</code>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is not possible to specify the configuration this way in WildFly.
Cache configuration changes in Wildfly should be done either modifying the cache configurations inside the application server configuration, or creating new caches with the desired tweaks and plugging them accordingly.
See examples below on how entity/collection specific configurations can be applied.</p>
</div>
</td>
</tr>
</table>
</div>
<div id="caching-provider-infinispan-config-example" class="exampleblock">
<div class="title">Example 28. Use custom Infinispan configuration</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.infinispan.cfg"
    value="my-infinispan-configuration.xml" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If the cache is configured as transactional, InfinispanRegionFactory automatically sets transaction manager so that the TM used by Infinispan is the same as TM used by Hibernate.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Cache configuration can differ for each type of data stored in the cache. In order to override the cache configuration template, use property <code>hibernate.cache.infinispan.<em>data-type</em>.cfg</code> where <code><em>data-type</em></code> can be one of:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>entity</code></dt>
<dd>
<p>Entities indexed by <code>@Id</code> or <code>@EmbeddedId</code> attribute.</p>
</dd>
<dt class="hdlist1"><code>immutable-entity</code></dt>
<dd>
<p>Entities tagged with <code>@Immutable</code> annotation or set as <code>mutable=false</code> in mapping file.</p>
</dd>
<dt class="hdlist1"><code>naturalid</code></dt>
<dd>
<p>Entities indexed by their <code>@NaturalId</code> attribute.</p>
</dd>
<dt class="hdlist1"><code>collection</code></dt>
<dd>
<p>All collections.</p>
</dd>
<dt class="hdlist1"><code>timestamps</code></dt>
<dd>
<p>Mapping <em>entity type</em> &#8594; <em>last modification timestamp</em>. Used for query caching.</p>
</dd>
<dt class="hdlist1"><code>query</code></dt>
<dd>
<p>Mapping <em>query</em> &#8594; <em>query result</em>.</p>
</dd>
<dt class="hdlist1"><code>pending-puts</code></dt>
<dd>
<p>Auxiliary caches for regions using invalidation mode caches.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>For specifying cache template for specific region, use region name instead of the <code><em>data-type</em></code>:</p>
</div>
<div id="caching-provider-infinispan-config-cache-example" class="exampleblock">
<div class="title">Example 29. Use custom cache template</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.infinispan.entities.cfg"
    value="custom-entities" /&gt;
&lt;property
    name="hibernate.cache.infinispan.query.cfg"
    value="custom-query-cache" /&gt;
&lt;property
    name="hibernate.cache.infinispan.com.example.MyEntity.cfg"
    value="my-entities" /&gt;
&lt;property
    name="hibernate.cache.infinispan.com.example.MyEntity.someCollection.cfg"
    value="my-entities-some-collection" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<div class="title">Use custom cache template in Wildfly</div>
<p>When applying entity/collection level changes inside JPA applications deployed in Wildfly, it is necessary to specify deployment name and persistence unit name:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property
    name="hibernate.cache.infinispan._war_or_ear_name_._unit_name_.com.example.MyEntity.cfg"
    value="my-entities" /&gt;
&lt;property
    name="hibernate.cache.infinispan._war_or_ear_name_._unit_name_.com.example.MyEntity.someCollection.cfg"
    value="my-entities-some-collection" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Cache configurations are used only as a template for the cache created for given region (usually each entity hierarchy or collection has its own region). It is not possible to use the same cache for different regions.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Some options in the cache configuration can also be overridden directly through properties. These are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>hibernate.cache.infinispan.<em>something</em>.eviction.strategy</code></dt>
<dd>
<p>Available options are <code>NONE</code>, <code>LRU</code> and <code>LIRS</code>.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.infinispan.<em>something</em>.eviction.max_entries</code></dt>
<dd>
<p>Maximum number of entries in the cache.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.infinispan.<em>something</em>.expiration.lifespan</code></dt>
<dd>
<p>Lifespan of entry from insert into cache (in milliseconds)</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.infinispan.<em>something</em>.expiration.max_idle</code></dt>
<dd>
<p>Lifespan of entry from last read/modification (in milliseconds)</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.infinispan.<em>something</em>.expiration.wake_up_interval</code></dt>
<dd>
<p>Period of thread checking expired entries.</p>
</dd>
<dt class="hdlist1"><code>hibernate.cache.infinispan.statistics</code></dt>
<dd>
<p>Globally enables/disable Infinispan statistics collection, and their exposure via JMX.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-XML" data-lang="XML">&lt;property name="hibernate.cache.infinispan.entity.eviction.strategy"
   value= "LRU"/&gt;
&lt;property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval"
   value= "2000"/&gt;
&lt;property name="hibernate.cache.infinispan.entity.eviction.max_entries"
   value= "5000"/&gt;
&lt;property name="hibernate.cache.infinispan.entity.expiration.lifespan"
   value= "60000"/&gt;
&lt;property name="hibernate.cache.infinispan.entity.expiration.max_idle"
   value= "30000"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>With the above configuration, you&#8217;re overriding whatever eviction/expiration settings were defined for the default entity cache name in the Infinispan cache configuration used, regardless of whether it&#8217;s the default one or user defined.
More specifically, we&#8217;re defining the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>All entities to use LRU eviction strategy</p>
</li>
<li>
<p>The eviction thread to wake up every 2 seconds (2000 milliseconds)</p>
</li>
<li>
<p>The maximum number of entities for each entity type to be 5000 entries</p>
</li>
<li>
<p>The lifespan of each entity instance to be 1 minute (600000 milliseconds).</p>
</li>
<li>
<p>The maximum idle time for each entity instance to be 30 seconds (30000 milliseconds).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You can also override eviction/expiration settings on a per entity/collection type basis in such way that the overriden settings only afftect that particular entity (i.e. <code>com.acme.Person</code>) or collection type (i.e. <code>com.acme.Person.addresses</code>).
Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;property name="hibernate.cache.infinispan.com.acme.Person.eviction.strategy"
   value= "LIRS"/&gt;</code></pre>
</div>
</div>
<div class="exampleblock">
<div class="content">
<div class="paragraph">
<p>Inside of Wildfly, same as with the entity/collection configuration override, eviction/expiration settings would also require deployment name and persistence unit information:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;property name="hibernate.cache.infinispan._war_or_ear_name_._unit_name_.com.acme.Person.eviction.strategy"
   value= "LIRS"/&gt;
&lt;property name="hibernate.cache.infinispan._war_or_ear_name_._unit_name_.com.acme.Person.expiration.lifespan"
   value= "65000"/&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>In versions prior to 5.1, <code>hibernate.cache.infinispan.<em>something</em>.expiration.wake_up_interval</code> was called <code>hibernate.cache.infinispan.<em>something</em>.eviction.wake_up_interval</code>.
Eviction settings are checked upon each cache insert, it is expiration that needs to be triggered periodically.
The old property still works, but its use is deprecated.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Property <code>hibernate.cache.infinispan.use_synchronization</code> that allowed to register Infinispan as XA resource in the transaction has been deprecated in 5.0 and is not honored anymore. Infinispan 2LC must register as synchronizations on transactional caches. Also, non-transactional cache modes hook into the current JTA/JDBC transaction as synchronizations.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="caching-provider-infinispan-remote">Remote Infinispan Caching</h4>
<div class="paragraph">
<p>Lately, several questions ( <a href="http://community.jboss.org/message/575814#575814">here</a> and <a href="http://community.jboss.org/message/585841#585841">here</a> ) have appeared in the Infinispan user forums asking whether it&#8217;d be possible to have an Infinispan second level cache that instead of living in the same JVM as the Hibernate code, it resides in a remote server, i.e. an Infinispan Hot Rod server.
It&#8217;s important to understand that trying to set up second level cache in this way is generally not a good idea for the following reasons:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The purpose of a JPA/Hibernate second level cache is to store entities/collections recently retrieved from database or to maintain results of recent queries.
So, part of the aim of the second level cache is to have data accessible locally rather than having to go to the database to retrieve it everytime this is needed.
Hence, if you decide to set the second level cache to be remote as well, you&#8217;re losing one of the key advantages of the second level cache: the fact that the cache is local to the code that requires it.</p>
</li>
<li>
<p>Setting a remote second level cache can have a negative impact in the overall performance of your application because it means that cache misses require accessing a remote location to verify whether a particular entity/collection/query is cached.
With a local second level cache however, these misses are resolved locally and so they are much faster to execute than with a remote second level cache.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>There are however some edge cases where it might make sense to have a remote second level cache, for example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You are having memory issues in the JVM where JPA/Hibernate code and the second level cache is running.
Off loading the second level cache to remote Hot Rod servers could be an interesting way to separate systems and allow you find the culprit of the memory issues more easily.</p>
</li>
<li>
<p>Your application layer cannot be clustered but you still want to run multiple application layer nodes.
In this case, you can&#8217;t have multiple local second level cache instances running because they won&#8217;t be able to invalidate each other for example when data in the second level cache is updated.
In this case, having a remote second level cache could be a way out to make sure your second level cache is always in a consistent state, will all nodes in the application layer pointing to it.</p>
</li>
<li>
<p>Rather than having the second level cache in a remote server, you want to simply keep the cache in a separate VM still within the same machine.
In this case you would still have the additional overhead of talking across to another JVM, but it wouldn&#8217;t have the latency of across a network.</p>
<div class="paragraph">
<p>The benefit of doing this is that:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Size the cache separate from the application, since the cache and the application server have very different memory profiles.
One has lots of short lived objects, and the other could have lots of long lived objects.</p>
</li>
<li>
<p>To pin the cache and the application server onto different CPU cores (using <em>numactl</em> ), and even pin them to different physically memory based on the NUMA nodes.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-04-05 16:05:02 +02:00
</div>
</div>
</body>
</html>